package net.sky.oa.service.system.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.annotation.Resource;

import net.sky.oa.dao.system.SysDeptDao;
import net.sky.oa.model.SysDept;
import net.sky.oa.service.system.SysDeptService;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.htsoft.core.service.impl.BaseServiceImpl;

@Service
@Transactional
public class SysDeptServiceImpl extends BaseServiceImpl<SysDept> implements SysDeptService {
	private SysDeptDao dao;

	public SysDeptServiceImpl() {}
	
	public SysDeptServiceImpl(SysDeptDao dao) {
		super(dao);
		this.dao = dao;
	}

	public List<SysDept> findAllDept() {
		return this.dao.findAllDept();
	}

	@Resource
	public void setDao(SysDeptDao dao) {
		super.setDao(dao);
		this.dao = dao;
	}
	
	private List<SysDept> alllist;
 
	public List<SysDept> findByParentId(Long pid) {
		List<SysDept> ds = dao.findByHql("from SysDept as sd where sd.parent.id=?", new Object[]{pid});
		if(ds == null || ds.size() == 0)return null;
		return ds;
	}
	
	/* (non-Javadoc)
	 * @see net.sky.oa.service.system.impl.getTreeMap#getTreeMap(java.lang.String)
	 */
	public TreeMap getTreeMap(String status){
		SysDept rootDept = this.get(0l);
		TreeMap<String, Object> rootMap = new TreeMap<String,Object>();
	    rootMap.put("id", "0");
	    if(rootDept != null){
	    	rootMap.put("text", rootDept.getName());
	    	
	    	StringBuffer sql = new StringBuffer("select new SysDept(id,name,status,parent) from SysDept as d where d.id>0")
	    		.append(status != null ? "and d.status = 1" : "and(d.status = 1 or d.status = 2)");
	    	
	    	alllist = this.dao.findByHql(sql.toString());
	    	if(alllist.size() > 0 ){
	    		rootMap.put("children", childrenTree(rootDept));
	    	}else {
	    		rootMap.put("leaf", true);
	    	}
	    }else {
	    	rootMap.put("text", "没有部门！");
	    	rootMap.put("leaf", true);
		}
	    rootMap.put("expanded", true);
	    
	    return rootMap;
	}
	
	private List<Map> childrenTree(SysDept dept){
		List<Map> children = new ArrayList<Map>();
		
		for(SysDept dep : alllist){
			if(dep.getParent() != null && !dep.getParent().getId().equals(dept.getId()))continue;
			
			TreeMap<String, Object> cmap = new TreeMap<String,Object>();
			cmap.put("id", dep.getId());
			
			if(dep.getStatus() == 2){
				cmap.put("text", dep.getName() + "&nbsp;(已禁用)");
			}else{
				cmap.put("text", dep.getName());
			}
			
			if(hasChildren(dep)){
				cmap.put("children",childrenTree(dep));
			}else {
				cmap.put("leaf", true);
			}
			children.add(cmap);
			cmap = null;
		}
		
		return children;
	}
	
	private boolean hasChildren(SysDept dept){
		for(SysDept dep : alllist){
			if(dep.getParent() != null && dep.getParent().getId().equals(dept.getId()))return true;
		}
		return false;
	}
	
	@Transactional(readOnly = true)
	public List<SysDept> findByName(String name) {
		return this.dao.findByName(name);
	}
	
	public List<SysDept> listDept(){
		return this.dao.listDept();
	}
	
	@Override
	public SysDept save(SysDept entity) {
		SysDept parent = this.get(entity.getParent().getId());
		String depPath = parent.getPath();
		Integer rank = parent.getRank();
		
		entity.setRank(rank + 1);
		
		boolean updata = true;
		if (entity.getId() == null) {
			updata = false;
			super.save(entity);
		}
		
		depPath = depPath + entity.getId() + ".";
		entity.setPath(depPath);
		super.save(entity);
		
		if(updata){
			this.saveChild(entity);
		}
		
		//return super.save(entity);
		return null;
	}
	
	public void saveChild(SysDept deptNode) {
		List<SysDept> list = this.findByParentId(deptNode.getId());
		if (list != null) {
			for (SysDept dep : list) {
				String depPath = deptNode.getPath() + dep.getId() + ".";
				dep.setPath(depPath);
				dep.setRank(deptNode.getRank() + 1);
				
				super.save(dep);
				this.saveChild(dep);
			}
		}
	}
	
	public List<SysDept> hql(String ids){
		return this.dao.findByHql("from SysDept d where d.id in("+ids+")");
	}
}